#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <yaml-cpp/yaml.h>
#include "qcustomplot/qcustomplot.h"
#include "qcpaxistickermeter.h"
#include "options.h"
#include "wavedisplay.h"
#include "yshiftsetting.h"
#include "xshiftsetting.h"
#include <log4qt/logger.h>
#include "serialworker.h"
#include "messageparser.h"

#define HEADS 4               // 磁头数
#define WAVE_NUM_PER_ROPE 2   // 曲线数
#define TEST_DATA_INTERVAL 10 // 10ms生成1个数据
#define REPLOT_INTERVAL 200   // 200ms刷新1次图形

//QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

struct Range {
    bool valid{false};
    double lower;
    double upper;
};

class MainWindow : public QMainWindow {
    Q_OBJECT

  public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void setupPlot();

  signals:
    void newData(QStringList data); // 收到数据

  private slots:
    void replot();                        // 定时绘制图表
    void genTestData();                   // 产生随机数据
    void saveStream(QStringList newData); // 实时保存数据到csv文件
    void onNewDataArrived(QStringList newData); // 绘图

    void onHorzScrollBarChanged(int value);
    void onxAxisChanged(QCPRange range);

    void on_actionTestStart_triggered();
    void on_actionTestPause_triggered();

    void on_actionConnect_triggered();
    void on_actionDisconnect_triggered();

    void onDisplayDistanceChanged(QAction *action);
    void on_actionShowTextBrowse_triggered();

    void on_actionAbout_triggered();

    void on_actionLoadFile_triggered();
    void on_actionFilter_triggered();

    void on_actionStart_triggered();
    void on_actionStop_triggered();
    void on_actionPause_triggered();

    void on_actionChannel_triggered();
    void on_actionEnlarge_triggered();
    void on_actionReduce_triggered();
    void on_actionYrange_triggered();
    void on_actionYShift_triggered();
    void on_actionSum_triggered();
    void on_actionLegend_triggered();

    void on_actionXShift_triggered();

protected:
    void showEvent(QShowEvent *event) override {
        // 确保在调用基类的showEvent之后再移动窗口
        QWidget::showEvent(event);
        int screenWidth = QApplication::desktop()->width();
        int screenHeight = QApplication::desktop()->height();
        this->move((screenWidth - this->width()) / 2, (screenHeight - this->height()) / 2);
    }
    bool eventFilter(QObject *obj, QEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
private:
    Ui::MainWindow *ui;

    QCustomPlot *mPlots[HEADS * WAVE_NUM_PER_ROPE];
    Range mYRange[HEADS * WAVE_NUM_PER_ROPE];
    Shift mYShift[HEADS * WAVE_NUM_PER_ROPE];
    XShift mXShift[HEADS];
    int mSelectedPlotIdx{-1};

    QTimer mTestTimer;
    QTimer mReplotTimer;

    bool mPlotting;
    bool mConnected;
    bool mSaveToFile{true};
    bool mPreSaveToFile{true};

    QString mPortName;
    QString mPortSpeed;
    QString mReceivedData; // 一条消息
    QString mWavelet{"db4"};
    const QString mCfgFile{"./config.yml"};
    const QString mSaveDir{"./data/"};
    int mDecLayerNum{4};
    int mSaveDays{30};
    QAction *mSelDspDist;

    DisplayChannel mDisplayChannel;

    unsigned long long mTicksPerM{500}; // 2mm一个数据
    unsigned long long mDataNum{0};
    unsigned long long mDisplayNum{mTicksPerM};

    QLabel *mConnectedLable; // 状态栏状态信息
    QLabel *mPacketLable;
    QLabel *mDistanceLable;
    QLabel *mDebugLable;

    Log4Qt::Logger* mLogger; // 用来保存日志记录器

    QFile *mCsvFile{nullptr};
    SerialWorker *mSerialWorker{nullptr};

    QColor mWaveColor[WAVE_NUM_PER_ROPE * 2] = {Qt::red, Qt::darkBlue, Qt::magenta, Qt::green};
    QString mWaveName[WAVE_NUM_PER_ROPE * 2] = {"LMA", "LF", "LMA-Flt", "LF-Flt"};

    MessageParser mMsgParser;

    void onMouseMoveInPlot(QMouseEvent *event, QCustomPlot *plot);
    void onGraphSelection(QCustomPlot *plot);
    void onLegendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item,
                             QCustomPlot *plot);

    void disable_test_controls();
    void disable_port_controls();
    void enable_controls();
    void openCsvFile(void);
    void closeCsvFile(void);
    void init();
    bool checkWaveName(const QString &wave);

    void readCfg();
    void saveCfg();

    void getYrange(int index);
    bool graphSelected();
    void showLegend(bool show);
};
#endif // MAINWINDOW_H
